import usocket

class TcpClient:

    def __init__(self):
        self.__socket = None
        self.__connected = False
        self.on_connect = None
        self.on_disconnect = None
        self.__timeout = None
    
    def __del__(self):
        self.close()
    
    def get_status(self):
        if self.__socket == None:
            return 0
        try:
            return self.__socket.getsocketsta()
        except Exception:
            return 0

    @property
    def connected(self):
        #self.check_status()
        return self.__connected

    def set_timeout(self, timeout):
        self.__timeout = timeout
        
    def connect(self, addr, port):
        """连接

        :param addr: 地址
        :type addr: str
        :param port: 端口
        :type port: int
        """
        if self.__socket == None:
            self.__socket = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
            self.__socket.settimeout(self.__timeout)
            self.__socket.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
            self.__socket.setsockopt(usocket.SOL_SOCKET, usocket.TCP_KEEPALIVE, 1)
        
        #print('Connect to server')
        try:
            self.__server = usocket.getaddrinfo(addr, port)[0][-1]
            self.__socket.connect(self.__server)
            self.__connected = True
            if self.on_connect:
                self.on_connect()
        except Exception as e:
            if e.args[0] == 104: #连接被重置
                self.__connected = False
            else:
                self.close()

    def send(self, data):
        try:
            if self.__socket != None:
                return self.__socket.send(data)
        except Exception as e:
            print(e)
            self.close()

    def receive(self, size = 255):
        try:
            if self.__socket != None:
                return self.__socket.recv(size)
        except Exception as e:
            print(e)
            self.close()
        return None

    def close(self):
        if self.__socket == None:
            return
        self.__connected = False
        self.__socket.close()
        self.__socket = None
        if self.on_disconnect:
                self.on_disconnect()
        